﻿#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<map>
#include<string>
using namespace std;
void test1() {
	//一、map的构造：
	  
	//1.列表构造：
	map<string, string> m = { {"left","左边"},{"right","右"},
						    {"up","上"},{"down","下"}};
	//注意：这里有两层构造：先构造处initializer_list类型，再调用map的构造函数
	   //initializer_list里面，发生隐式类型转化：{ "","" }被编译器识别为pair<T,K>类型

	//二、插入：
	map<string, string> m1;
	//1.先构造一个pair对象,在插入
	pair<string, string>kv1("dog", "狗");
	m1.insert(kv1);
	//2.构造一个匿名对象插入
	m1.insert(pair<string, string>("cat", "猫"));
    //3.特殊语法：
	m1.insert(make_pair("lion", "狮子"));
	//4.最简便：隐式类型转化
	m1.insert({ "tiger","虎" });


	//三、遍历：
	//1.正向迭代器：

	//注意：map的迭代器也是一个封装的类，不是简单的指向一个节点的指针
	//      内部也有一些运算符重载


	map<string, string>::iterator it = m.begin();
	map<string, string>::iterator it1 = m1.begin();
	while (it != m.end()) {
		//cout << *it << " ";  报错，因为*it只是拿到了pair ,而pair类并未对<<进行运算法重载

		cout << (*it).first << "：" << (*it).second << endl;
	
		//pair类重载了运算符 ->
		cout << it.operator->()->first << "：" << it.operator->()->second << endl;
	    
		//相当于：（简化）
		cout << it->first << "：" << it->second << endl;

		it++;
	}
	while (it1 != m1.end()) {
		cout << (*it1).first << "：" << (*it1).second << endl;
		cout << it1.operator->()->first << "：" << it1.operator->()->second << endl;
		cout << it1->first << "：" << it1->second << endl;
		it1++;
	}


	//2.反向迭代器：
	map<string, string>::reverse_iterator rit = m.rbegin();
	map<string, string>::reverse_iterator rit1 = m1.rbegin();
	while (rit != m.rend()) {
		cout << (*rit).first << "：" << (*rit).second << endl;
		cout << rit.operator->()->first << "：" << rit.operator->()->second << endl;
		cout << rit->first << "：" << rit->second << endl;
		rit++;
	}
	while (rit1 != m1.rend()) {
		cout << (*rit1).first << "：" << (*rit1).second << endl;
		cout << rit1.operator->()->first << "：" << rit1.operator->()->second << endl;
		cout << rit1->first << "：" << rit1->second << endl;
		rit1++;
	}

	//3.范围for：
	for (auto p : m) { //p是map存的的pair对象
		cout << p.first << "：" << p.second << endl;
	}
	for (auto p1 : m1) { //p是map存的的pair对象
		cout << p1.first << "：" << p1.second << endl;
	}

}
void test2() {
	map<string, string> m1;
	//1.先构造一个pair对象,在插入
	pair<string, string>kv1("dog", "狗");
	m1.insert(kv1);
	//2.构造一个匿名对象插入
	m1.insert(pair<string, string>("cat", "猫"));
	//3.特殊语法：
	m1.insert(make_pair("lion", "狮子"));
	//4.最简便：隐式类型转化
	m1.insert({ "tiger","虎" });


	//四、查找
	/*string str;
	while (cin >> str) {
		auto ret = m1.find(str);
		if (ret != m1.end()) {
			cout << "->" << ret->second << endl;
		}
		else {
			cout << "无此单词" << endl;
		}*/
	//}

	//五、删除

	//1.根据key删除：
	m1.erase("cat");
	for (auto p1 : m1) { //p是map存的的pair对象
		cout << p1.first << "：" << p1.second << endl;
	}
	//2.输入迭代器删除：
	auto it = m1.find("dog");
	m1.erase(it);
	for (auto p1 : m1) { //p是map存的的pair对象
		cout << p1.first << "：" << p1.second << endl;
	}

	//3.根据一段迭代器区间删除:
	//语法：iterator  erase(const_iterator first, const_iterator last);
}

void test3() {
	//map的迭代器和operator[]的使用：
	// 利⽤find和iterator修改功能，统计⽔果出现的次数
	string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜",
	"苹果", "香蕉", "苹果", "香蕉" };
	map<string, int> countMap;
	for (const auto& str : arr)
	{
		// 先查找⽔果在不在map中
		// 1、不在，说明⽔果第⼀次出现，则插⼊{⽔果, 1}
		// 2、在，则查找到的节点中⽔果对应的次数++
		auto it = countMap.find(str);
		if (it == countMap.end())
		{
			countMap.insert({ str, 1 });
		}
		else
		{
			it->second++;  //相当于：it.operator->()->second++ 
		}
	}
	for (const auto& e : countMap)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	//版本2：
	map<string, int> countMap1;
	for (const auto& str : arr)
	{
		//底层解析：map类重载了操作符[]
		//mapped_type& operator[] (const key_type& k){
		//        pair<iterator,bool> ret=insert( { k, mapped_type(0)} ) ; 
		//    //原本没有：ret： pair<新插入的pair的迭代器，true>
		// 
		//    //原本就有：ret： pair<原本就有的pair的迭代器,false>
		//     
		//    //然后：auto it=ret.first 拿到上面的迭代器
		//            return it->second ; //返回mapped_type的引用  
		

		// []先查找⽔果在不在map中：
	    // 1、不在，说明⽔果第⼀次出现，则插⼊{⽔果, 0}，同时返回次数的引⽤，
	    //	++⼀下就变成1次了
		// 2、在，则返回⽔果对应的次数++
			countMap1[str]++;
	}
	for (const auto& e : countMap1)
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	//基于上述原理发现：map的operator[]()函数充当了：查找key、插入pair、修改second三个功能

	//使用：
	pair<map<string, int>::iterator, bool> ret;
	ret = countMap.insert({ "桃子",0 });
	if (ret.second==false) {
		cout << ret.first->first << "已存在" << "：" << ret.first->second << endl;
	}
	else {
		cout << ret.first->first << "刚插入" << "：" << ret.first->second+1 << endl;
	}
}
int main() {
	//test1();
	//test2();
	test3();
	return 0;
}